package com.azt.novel.user.service.impl;


import com.azt.novel.common.auth.JwtUtils;
import com.azt.novel.common.constant.DatabaseConsts;
import com.azt.novel.common.constant.ErrorCodeEnum;
import com.azt.novel.common.constant.SystemConfigConsts;
import com.azt.novel.common.resp.RestResp;
import com.azt.novel.config.exception.BusinessException;
import com.azt.novel.user.dao.entity.UserInfo;
import com.azt.novel.user.dao.mapper.UserInfoMapper;
import com.azt.novel.user.dto.req.UserLoginReqDto;
import com.azt.novel.user.dto.req.UserRegisterReqDto;
import com.azt.novel.user.dto.resp.UserInfoRespDto;
import com.azt.novel.user.dto.resp.UserLoginRespDto;
import com.azt.novel.user.dto.resp.UserRegisterRespDto;
import com.azt.novel.user.manager.redis.VerifyCodeManager;
import com.azt.novel.user.service.IUserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author azt
 * @since 2023-12-02
 */
@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Resource
    private VerifyCodeManager verifyCodeManager;

    @Resource
    private UserInfoMapper userInfoMapper;


    private JwtUtils jwtUtils;


    @Override
    public RestResp<UserInfoRespDto> getUserinfo(Long userId) {
        UserInfo userInfo = userInfoMapper.selectById(userId);
        UserInfoRespDto userInfoRespDto = UserInfoRespDto.builder().build();
        BeanUtils.copyProperties(userInfo,userInfoRespDto);
        return RestResp.ok(userInfoRespDto);
    }

    @Override
    public RestResp<UserLoginRespDto> login(UserLoginReqDto dto) {
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getUsername,dto.getUsername())
                .last("limit 1");
        UserInfo userInfo = userInfoMapper.selectOne(userInfoLambdaQueryWrapper);
        if(Objects.isNull(userInfo)){
            //用户不存在
            throw new BusinessException(ErrorCodeEnum.USER_ACCOUNT_NOT_EXIST);
        }
        //用户存在，判断密码是否正确
        if(!Objects.equals(userInfo.getPassword(),
                DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)))){
            //不正确
            throw new BusinessException(ErrorCodeEnum.USER_PASSWORD_ERROR);
        }

        //用户密码正确，生成JWT并返回
        return RestResp.ok(
                UserLoginRespDto.builder()
                        .nickName(userInfo.getUsername())
                        .uid(userInfo.getId())
                        .token(jwtUtils.generateToken(userInfo.getId(), SystemConfigConsts.NOVEL_FRONT_KEY))
                        .build()
        );
    }

    @Override
    public RestResp<UserRegisterRespDto> register(UserRegisterReqDto dto) {
        //校验图形验证码是否正确
        if(!verifyCodeManager.imgVerifyCodeOk(dto.getSessionId(),dto.getVelCode())){
            //错误
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY_CODE_ERROR);
        }
        //校验手机号是否被注册
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getUsername,dto.getUsername())
                .last("limit 1");
        if(userInfoMapper.selectCount(userInfoLambdaQueryWrapper)>0){
            //已注册
            throw new BusinessException(ErrorCodeEnum.USER_NAME_EXIST);
        }

        //注册成功
        UserInfo userInfo = new UserInfo();
        userInfo.setPassword(DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)));
        userInfo.setUsername(dto.getUsername());
        userInfo.setCreateTime(LocalDateTime.now());
        userInfo.setUpdateTime(LocalDateTime.now());
        userInfo.setSalt("0");

        //插入数据库
        userInfoMapper.insert(userInfo);

        //删除验证码图片
        verifyCodeManager.removeImgVerifyCode(dto.getSessionId());

        //生成JWT并返回
        return RestResp.ok(UserRegisterRespDto.builder()
                .token(jwtUtils.generateToken(userInfo.getId(), SystemConfigConsts.NOVEL_FRONT_KEY))
                .uid(userInfo.getId())
                .build());
    }


    @Override
    public RestResp<List<UserInfoRespDto>> listUserInfoByIds(List<Long> userIds) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(DatabaseConsts.CommonColumnEnum.ID.getName(), userIds);
        return RestResp.ok(
                userInfoMapper.selectList(queryWrapper).stream().map(v -> UserInfoRespDto.builder()
                        .id(v.getId())
                        .username(v.getUsername())
                        .userPhoto(v.getUserPhoto())
                        .build()).collect(Collectors.toList()));
    }


}
